home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Mac Format 1995 June
/
MacFormat 25.iso
/
Shareware City
/
Developers
/
OutOfPhase1.1 Source
/
OutOfPhase Folder
/
WaveTableStorageDisplay.c
< prev
next >
Wrap
Text File
|
1994-08-23
|
9KB
|
263 lines
/* WaveTableStorageDisplay.c */
/*****************************************************************************/
/* */
/* Out Of Phase: Digital Music Synthesis on General Purpose Computers */
/* Copyright (C) 1994 Thomas R. Lawrence */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 2 of the License, or */
/* (at your option) any later version. */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program; if not, write to the Free Software */
/* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
/* */
/* Thomas R. Lawrence can be reached at tomlaw@world.std.com. */
/* */
/*****************************************************************************/
#include "MiscInfo.h"
#include "Audit.h"
#include "Debug.h"
#include "Definitions.h"
#include "WaveTableStorageDisplay.h"
#include "Array.h"
#include "Memory.h"
#include "DataMunging.h"
struct WaveTableStorDispRec
{
NumBitsType NumBits;
long FramesPerTable;
ArrayRec* TableArray; /* of largefixedsigned[]'s */
};
/* create a new, empty wave table storage display object */
WaveTableStorDispRec* NewWaveTableStorDisp(NumBitsType NumBits, long NumFrames)
{
WaveTableStorDispRec* StorDisp;
ERROR((NumBits != eSample8bit) && (NumBits != eSample16bit),PRERR(ForceAbort,
"NewWaveTableStorDisp: bad number of bits"));
ERROR((NumFrames != 2) && (NumFrames != 4) && (NumFrames != 8) && (NumFrames != 16)
&& (NumFrames != 32) && (NumFrames != 64) && (NumFrames != 128)
&& (NumFrames != 256) && (NumFrames != 512) && (NumFrames != 1024)
&& (NumFrames != 2048) && (NumFrames != 4096) && (NumFrames != 8192)
&& (NumFrames != 16384) && (NumFrames != 32768) && (NumFrames != 65536),
PRERR(ForceAbort,"NewWaveTableStorDisp: bad number of frames"));
StorDisp = (WaveTableStorDispRec*)AllocPtrCanFail(sizeof(WaveTableStorDispRec),
"WaveTableStorDispRec");
if (StorDisp == NIL)
{
FailurePoint1:
return NIL;
}
StorDisp->NumBits = NumBits;
StorDisp->FramesPerTable = NumFrames;
StorDisp->TableArray = NewArray();
if (StorDisp->TableArray == NIL)
{
FailurePoint2:
ReleasePtr((char*)StorDisp);
goto FailurePoint1;
}
return StorDisp;
}
/* dispose of the wave table storage object */
void DisposeWaveTableStorDisp(WaveTableStorDispRec* StorDisp)
{
long Limit;
long Scan;
CheckPtrExistence(StorDisp);
Limit = ArrayGetLength(StorDisp->TableArray);
for (Scan = 0; Scan < Limit; Scan += 1)
{
ReleasePtr((char*)ArrayGetElement(StorDisp->TableArray,Scan));
}
DisposeArray(StorDisp->TableArray);
ReleasePtr((char*)StorDisp);
}
/* get the number of frames per table */
long WaveTableStorDispNumFramesPerTable(WaveTableStorDispRec* StorDisp)
{
CheckPtrExistence(StorDisp);
return StorDisp->FramesPerTable;
}
/* get the number of tables */
long WaveTableStorDispNumTables(WaveTableStorDispRec* StorDisp)
{
CheckPtrExistence(StorDisp);
return ArrayGetLength(StorDisp->TableArray);
}
/* get the number of bits for the wave table */
NumBitsType WaveTableStorDispNumBits(WaveTableStorDispRec* StorDisp)
{
CheckPtrExistence(StorDisp);
return StorDisp->NumBits;
}
/* change the number of bits for the wave table */
void SetWaveTableStorDispNumBits(WaveTableStorDispRec* StorDisp,
NumBitsType NewNumBits)
{
CheckPtrExistence(StorDisp);
ERROR((NewNumBits != eSample8bit) && (NewNumBits != eSample16bit),PRERR(ForceAbort,
"SetWaveTableStorDispNumBits: bad number of bits"));
StorDisp->NumBits = NewNumBits;
}
/* get a reference to a table. this is NOT copied, and there is no type information. */
/* The last element is a repeat of the first, and is provided for making anti-aliasing */
/* more efficient. */
largefixedsigned* WaveTableStorDispGetTable(WaveTableStorDispRec* StorDisp,
long Index)
{
CheckPtrExistence(StorDisp);
ERROR((Index < 0) || (Index >= WaveTableStorDispNumTables(StorDisp)),
PRERR(ForceAbort,"WaveTableStorDispGetTable: index out of range"));
return (largefixedsigned*)ArrayGetElement(StorDisp->TableArray,Index);
}
/* append a new (zeroed out) table to the end of the array */
MyBoolean WaveTableStorDispAppendEntry(WaveTableStorDispRec* StorDisp)
{
largefixedsigned* NewSlice;
long Scan;
CheckPtrExistence(StorDisp);
NewSlice = (largefixedsigned*)AllocPtrCanFail(sizeof(largefixedsigned)
* (StorDisp->FramesPerTable + 1),"WaveTableStorDispRec slice");
/* + 1 used for the antialiasing slot */
if (NewSlice == NIL)
{
FailurePoint1:
return False;
}
if (!ArrayAppendElement(StorDisp->TableArray,NewSlice))
{
FailurePoint2:
ReleasePtr((char*)NewSlice);
goto FailurePoint1;
}
for (Scan = 0; Scan < StorDisp->FramesPerTable + 1; Scan += 1)
{
PRNGCHK(NewSlice,&(NewSlice[Scan]),sizeof(NewSlice[Scan]));
NewSlice[Scan] = 0;
}
return True;
}
/* put a value into a frame in a table */
void WaveTableStorDispSetFrame(WaveTableStorDispRec* StorDisp,
long TableIndex, long FrameIndex, largefixedsigned Value)
{
largefixedsigned* TheSlice;
CheckPtrExistence(StorDisp);
ERROR((TableIndex < 0) || (TableIndex >= WaveTableStorDispNumTables(StorDisp)),
PRERR(ForceAbort,"WaveTableStorDispSetFrame: table index out of range"));
ERROR((FrameIndex < 0) || (FrameIndex >= StorDisp->FramesPerTable),
PRERR(ForceAbort,"WaveTableStorDispSetFrame: frame in table index out of range"));
TheSlice = WaveTableStorDispGetTable(StorDisp,TableIndex);
PRNGCHK(TheSlice,&(TheSlice[FrameIndex]),sizeof(TheSlice[FrameIndex]));
TheSlice[FrameIndex] = Value;
if (FrameIndex == 0)
{
PRNGCHK(TheSlice,&(TheSlice[StorDisp->FramesPerTable]),
sizeof(TheSlice[StorDisp->FramesPerTable]));
TheSlice[StorDisp->FramesPerTable] = Value; /* anti-aliasing loopback value */
}
}
/* get a value from a frame in a table */
largefixedsigned WaveTableStorDispGetFrame(WaveTableStorDispRec* StorDisp,
long TableIndex, long FrameIndex)
{
largefixedsigned* TheSlice;
CheckPtrExistence(StorDisp);
ERROR((TableIndex < 0) || (TableIndex >= WaveTableStorDispNumTables(StorDisp)),
PRERR(ForceAbort,"WaveTableStorDispGetFrame: table index out of range"));
ERROR((FrameIndex < 0) || (FrameIndex >= StorDisp->FramesPerTable),
PRERR(ForceAbort,"WaveTableStorDispGetFrame: frame in table index out of range"));
TheSlice = WaveTableStorDispGetTable(StorDisp,TableIndex);
PRNGCHK(TheSlice,&(TheSlice[FrameIndex]),sizeof(TheSlice[FrameIndex]));
return TheSlice[FrameIndex];
}
/* make a duplicate of the wave table */
WaveTableStorDispRec* WaveTableStorDispDuplicate(WaveTableStorDispRec* Original)
{
WaveTableStorDispRec* Copy;
long Limit;
long Scan;
CheckPtrExistence(Original);
Copy = (WaveTableStorDispRec*)AllocPtrCanFail(sizeof(WaveTableStorDispRec),
"WaveTableStorDispRec");
if (Copy == NIL)
{
FailurePoint1:
return NIL;
}
Copy->NumBits = Original->NumBits;
Copy->FramesPerTable = Original->FramesPerTable;
Copy->TableArray = NewArray();
if (Copy->TableArray == NIL)
{
FailurePoint2:
ReleasePtr((char*)Copy);
goto FailurePoint1;
}
Limit = ArrayGetLength(Original->TableArray);
for (Scan = 0; Scan < Limit; Scan += 1)
{
char* Temp;
Temp = CopyPtr((char*)ArrayGetElement(Original->TableArray,Scan));
if (Temp == NIL)
{
FailurePoint3:
Limit = ArrayGetLength(Copy->TableArray);
for (Scan = 0; Scan < Limit; Scan += 1)
{
ReleasePtr((char*)ArrayGetElement(Copy->TableArray,Scan));
}
DisposeArray(Copy->TableArray);
goto FailurePoint2;
}
SetTag(Temp,"WaveTableStorDispRec: slice");
if (!ArrayAppendElement(Copy->TableArray,Temp))
{
FailurePoint3a:
ReleasePtr((char*)Temp);
goto FailurePoint3;
}
}
return Copy;
}